#pragma once

#include <vector>
#include <unordered_map>

#include "OMIT_MacroDefines.h"

namespace OMIT_NAMESPACE
{
    template <typename T>
    class randAccessSet
    {
    public:
		void insert(T* e);
		void erase(T* e);

		auto begin() noexcept { return _dataVec.begin(); }
		auto begin() const noexcept { return _dataVec.begin(); }
		auto end() noexcept { return _dataVec.end(); }
		auto end() const noexcept { return _dataVec.end(); }

		T* operator[](std::size_t i) const noexcept { return _dataVec[i]; }

		T* at(std::size_t i) const { return _dataVec.at(i); }

		std::size_t size() const noexcept { return _dataVec.size(); }

		void reserve(std::size_t n) {
			_dataVec.reserve(n);
			_dataMap.reserve(n);
		}
		void clear() noexcept {
			_dataVec.clear();
			_dataMap.clear();
		}

		const std::vector<T*>& vec() const noexcept { return _dataVec; }

		std::size_t idx(T* e) const { return _dataMap.at(e); }

		bool contains(T* e) const { return _dataMap.find(e) != _dataMap.end(); }

		bool empty() const noexcept { return _dataVec.empty(); }
	private:
		std::unordered_map<T*, std::size_t> _dataMap;
		std::vector<T*> _dataVec;
	};
}

#include "OMIT_RandAccessSet.inl"